package com.zxt.mq.mvc.log.retry;

import com.zxt.mq.config.rabbitmq.RabbitData;
import com.zxt.mq.config.rabbitmq.RabbitUtil;
import com.zxt.mq.mvc.log.send.MessageSendLogService;
import com.zxt.mq.mvc.log.send.zdomain.MessageSendLog;

import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;

import javax.annotation.Resource;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.thread.ThreadFactoryBuilder;


/**
 * <p>
 * DDS 接收数据监听
 * </p>
 *
 * @author hankliu
 * @since 2022/5/11 17:27
 */
@Service
public class RetryService {
    @Resource
    private MessageSendLogService messageSendLogService;
    @Resource
    private RabbitUtil rabbitUtil;
    protected ScheduledThreadPoolExecutor scheduledExecutor;


    /**
     * 开启重发轮询任务
     *
     * @param delay 轮询时间间隔
     * @param unit  时间单位
     */
    public void startResend(long delay, TimeUnit unit) {
        if (scheduledExecutor != null) {
            scheduledExecutor.shutdown();
        }
        ThreadFactory factory = ThreadFactoryBuilder.create().setNamePrefix("MESSAGE_RESEND").build();
        scheduledExecutor = new ScheduledThreadPoolExecutor(1, factory);
        scheduledExecutor.schedule(this::resend, delay, unit);
    }

    /**
     * 失败消息重发
     */
    public void resend() {
        List<MessageSendLog> failList = messageSendLogService.listFail();
        if (CollUtil.isNotEmpty(failList)) {
            for (MessageSendLog v : failList) {
                // 如果大于等于最大发送次数直接退出
                if (v.getSendTimes() >= v.getMaxSend()) {
                    // 标记为死亡
                    messageSendLogService.setMessageToAlreadyDead(v);
                    continue;
                }
                if (LocalDateTime.now().isAfter(v.getSendTime().plusSeconds(v.getIntervalTime()))) {
                    rabbitUtil.sendMessage(v.getExchangeName(),
                                           v.getRouterKey(),
                                           new RabbitData().setSendMsg(v.getSendMsg()).setUri(v.getUri()));
                }
            }
        }
    }

}
